package be.android.forap.gui;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.Map;

import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.simalliance.openmobileapi.Reader;

import com.dropbox.client2.exception.DropboxException;

import be.android.forap.ForAp;
import be.android.forap.R;
import be.android.forap.crypto.KeyServerUtil;
import be.android.forap.crypto.PGPEncryption;
import be.android.forap.crypto.CryptoUtil;
import be.android.forap.dataprovider.ContactUtil;
import be.android.forap.javacard.SecureElement;
import be.android.forap.sync.AccountAuthenticatorService;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Environment;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.text.InputType;
import android.text.TextUtils;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AutoCompleteTextView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;


public class SettingsActivity extends PreferenceActivity {

	private static final int SELECT_FOLDER_AND_WRITE = 0;

	private boolean clickHandled = false;
	private OutputStream secretOut; 
	private OutputStream publicOut;
	private ProgressDialog progressDialog;
	private SharedPreferences settings;

	private ForAp mApp;


	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		addPreferencesFromResource(R.xml.preferences);

		mApp = ForAp.getInstance();

		Preference pref_username = findPreference("username");
		pref_username.setSummary(mApp.getUser());

		initKeyInfoPref();

		findPreference("sendPGPkeypair").setOnPreferenceClickListener(sendKey);
		findPreference("syncDropbox").setOnPreferenceClickListener(forceSync);

		initSmartCardInfo();
	}





	private void initKeyInfoPref() {
		Preference pref_keyLength = findPreference("keyLength");
		Preference pref_keyAlgorithm = findPreference("keyAlgorithm");
		Preference pref_keyFingerprint = findPreference("keyFingerprint");
		Preference pref_keyDisplay = findPreference("keyDisplay");
		String pk = mApp.getPublicKey();
		if(pk.equals("")){
			pref_keyLength.setSummary("Error reading the keyfile");
			pref_keyAlgorithm.setSummary("Error reading the keyfile");
			pref_keyDisplay.setSummary("Error reading the keyfile");
		}else{
			InputStream keyIn = new ByteArrayInputStream(pk.getBytes());
			PGPPublicKey key;
			try {
				key = PGPEncryption.readPublicKey(keyIn);
				keyIn.close();				 
				pref_keyLength.setSummary(Integer.toString(key.getBitStrength()));
				pref_keyAlgorithm.setSummary(CryptoUtil.getPublicKeyAlgorithm(key.getAlgorithm()));
				pref_keyFingerprint.setSummary(CryptoUtil.toHex(key.getFingerprint()));
				pref_keyDisplay.setSummary(pk);
			} catch (IOException e1) {
				pref_keyLength.setSummary("Error reading the keyfile");
				pref_keyAlgorithm.setSummary("Error reading the keyfile");
				pref_keyDisplay.setSummary("Error reading the keyfile");
				e1.printStackTrace();
			} catch (PGPException e1) {
				pref_keyLength.setSummary("Error reading the keyfile");
				pref_keyAlgorithm.setSummary("Error reading the keyfile");
				pref_keyDisplay.setSummary("Error reading the keyfile");
				e1.printStackTrace();
			}
		}
	}

	Preference.OnPreferenceClickListener sendKey = new Preference.OnPreferenceClickListener() {
		public boolean onPreferenceClick(Preference preference) {
			showDialogSendKey();
			return true;
		}
	};

	Preference.OnPreferenceClickListener forceSync = new Preference.OnPreferenceClickListener() {
		public boolean onPreferenceClick(Preference preference) {
			AccountAuthenticatorService.forceSyncAccount(getApplicationContext());
			return true;
		}
	};

	private void initSmartCardInfo() {
		if(SecureElement.isSecureElementPresent()){
			Preference pref_sc_present = findPreference("smartCardPresent");
			pref_sc_present.setTitle("Secure SDCard detected");
		}
		Reader[] r = SecureElement.getAllSmartCardReaders();

		String readerName = "No readers present.";
		int readersLength = 0;
		String atr = "No secure element present";
		if(r!=null){
			readersLength = r.length;
			if(readersLength>0)
				readerName = r[0].getName();
			Reader[] sr = SecureElement.getSecureSmartCardReaders();
			try {
				if(sr.length>0)
					atr = CryptoUtil.toHex(sr[0].openSession().getATR());
					
			} catch (IOException e) {
				atr = "Error: session couldn't be opened: "+e.getMessage();
			}
		}

		Preference pref_sc_readerName = findPreference("readerName");
		pref_sc_readerName.setSummary(readerName);
		Preference pref_sc_readerAmount = findPreference("readersAmount");
		pref_sc_readerAmount.setSummary(String.valueOf(readersLength));
		Preference pref_sc_atr = findPreference("ATR");
		pref_sc_atr.setSummary(atr);
	}




	private String[] choicesSendKey = {"Send SMS", "Send Email", "Save as file"};

	private void showDialogSendKey(){		
		AlertDialog.Builder sel_output = new AlertDialog.Builder(this);
		sel_output.setTitle("Select ouput method")
		.setItems(choicesSendKey, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int index) {
				procesSendKey(index);
			}
		})
		.create();
		sel_output.show();
	}


	private void procesSendKey(int index) {
		switch(index){
		case 0:
			AlertDialog.Builder sendsms = new AlertDialog.Builder(this);
			sendsms.setTitle("Enter contact:");
			final AutoCompleteTextView autoInput = new AutoCompleteTextView(this);
			//ForapAdapter forapdata = new ForapAdapter(this,this,false,true);			
			SimpleAdapter mAdapter = new SimpleAdapter(this, ContactUtil.getContactsWithPhone(this), R.layout.autocomplete_dropdown_phone ,new String[] { "Name", "Phone" , "Type" }, new int[] { R.id.ccontName, R.id.ccontNo, R.id.ccontType });
			autoInput.setAdapter(mAdapter);
			autoInput.setInputType(InputType.TYPE_CLASS_PHONE);
			autoInput.setHint("To..");
			autoInput.setThreshold(1);
			autoInput.setOnItemClickListener(new OnItemClickListener() {

				public void onItemClick(AdapterView<?> av, View v, int index, long arg) {
					Map<String, String> map = (Map<String, String>) av.getItemAtPosition(index);
					Iterator<String> myVeryOwnIterator = map.keySet().iterator();
					while(myVeryOwnIterator.hasNext()) {
						String key=(String)myVeryOwnIterator.next();
						String value=(String)map.get(key);
						autoInput.setFocusable(false);
						autoInput.setFocusableInTouchMode(false);
						autoInput.setText(value);            
						autoInput.setFocusable(true);
						autoInput.setFocusableInTouchMode(true);
					}               
				}

			});
			sendsms.setView(autoInput);
			sendsms.setPositiveButton("Ok", new DialogInterface.OnClickListener() {  
				public void onClick(DialogInterface dialog, int whichButton) {
					String selected = autoInput.getText().toString() ;
					if(!TextUtils.isEmpty(selected)){
						try {
							String destinationAddress=selected;
							Intent sendSms = new Intent(getApplicationContext(), SmsActivity.class);
							sendSms.putExtra("phoneNumber",destinationAddress);
							sendSms.putExtra("message",KeyServerUtil.exchangeKeySMS(getApplicationContext()));
							startActivity(sendSms);
						} catch (NoSuchAlgorithmException e) {
							Toast.makeText(getApplicationContext(), "DIGEST ERROR: Sms was not send!", Toast.LENGTH_SHORT).show();
						} catch (DropboxException e) {
							Toast.makeText(getApplicationContext(), "DROPBOX ERROR: Sms was not send!", Toast.LENGTH_SHORT).show();
						}
					} else 
						Toast.makeText(getApplicationContext(), "Sms was not send! No contact selected", Toast.LENGTH_SHORT).show();					
				}  
			});  

			sendsms.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

				public void onClick(DialogInterface dialog, int which) {
					Toast.makeText(getApplicationContext(), "Sms was not send!", Toast.LENGTH_SHORT).show();
					return;   
				}
			});
			sendsms.create();
			sendsms.show();

			break;
		case 1:
			//Send as Email
			try{
				Intent i = new Intent(Intent.ACTION_SEND);
				i.setType("message/rfc822");
				i.putExtra(Intent.EXTRA_EMAIL  , new String[]{"recipient@example.com"});
				i.putExtra(Intent.EXTRA_SUBJECT, "");
				i.putExtra(Intent.EXTRA_TEXT , KeyServerUtil.exchangeKeyEmail(getApplicationContext()));
				startActivity(Intent.createChooser(i, "Send mail..."));
			} catch (android.content.ActivityNotFoundException ex) {
				Toast.makeText(this, "There are no email clients installed.", Toast.LENGTH_SHORT).show();
			} catch (DropboxException e) {
				Toast.makeText(getApplicationContext(), "DROPBOX ERROR: Sms was not send!", Toast.LENGTH_SHORT).show();
			}
			break;
		case 2://Save to file
			String state = Environment.getExternalStorageState();
			if (Environment.MEDIA_MOUNTED.equals(state)) {
				File sdCard = Environment.getExternalStorageDirectory();
				final File dir = new File (sdCard.getAbsolutePath() + "/ForAp");
				if(!dir.exists())
					dir.mkdirs();
				Intent selectFile = new Intent(this, FileExplorerActivity.class);
				selectFile.putExtra(FileExplorerActivity.START_PATH, "/sdcard/forap");
				selectFile.putExtra(FileExplorerActivity.SELECT_ONLY_FOLDER_WRITE, true);
				startActivityForResult(selectFile, SELECT_FOLDER_AND_WRITE);
			}else{
				Toast.makeText(getApplicationContext(), "Error, no (writable) sdcard is mounted!", Toast.LENGTH_SHORT).show();
			}
			break;
		}


	}

	protected void onActivityResult(int requestCode, int resultCode, Intent data) {

		if (requestCode == SELECT_FOLDER_AND_WRITE) {
			if (resultCode == Activity.RESULT_OK) {		
				final String folderPath = data.getStringExtra(FileExplorerActivity.RESULT_PATH);
				String fileName = "publickey.asc";
				final String content = ForAp.getInstance().getPublicKey();

				AlertDialog.Builder alert = new AlertDialog.Builder(this);
				alert.setTitle("Saving to sd card");

				alert.setMessage("Filename: "+folderPath+"/"+fileName);				
				alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {  
					public void onClick(DialogInterface dialog, int whichButton) {
						FileOutputStream fos;
						try {	
							File file = new File(folderPath, "publickey.asc");
							FileOutputStream f = new FileOutputStream(file,false);
							f.write(content.getBytes());
							f.close();
							Toast.makeText(getApplicationContext(), "File was saved succesfully", Toast.LENGTH_SHORT).show();
						} catch (FileNotFoundException e) {
							Toast.makeText(getApplicationContext(), "Error while saving the file!", Toast.LENGTH_SHORT).show();
							e.printStackTrace();
						}	catch (IOException e) {
							Toast.makeText(getApplicationContext(), "Error while saving the file!", Toast.LENGTH_SHORT).show();
							e.printStackTrace();
						}					                
					}  
				});  

				alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

					public void onClick(DialogInterface dialog, int which) {
						Toast.makeText(getApplicationContext(), "File was not saved!", Toast.LENGTH_SHORT).show();
						return;   
					}
				});
				alert.show();
			} else if (resultCode == Activity.RESULT_CANCELED) {
				((TextView) findViewById(R.id.en_textview_selectedFile)).setText("Error selecting a folder");
			}
		}

	}
}

/*



	private PreferenceScreen findPreferenceScreenForPreference( String key, PreferenceScreen screen ) {
		if( screen == null ) {
			screen = getPreferenceScreen();
		}

		PreferenceScreen result = null;

		android.widget.Adapter ada = screen.getRootAdapter();
		for( int i = 0; i < ada.getCount(); i++ ) {
			String prefKey = ((Preference)ada.getItem(i)).getKey();
			if( prefKey != null && prefKey.equals( key ) ) {

				Log.i("SCREENINNER",prefKey);
				return screen;
			}
			if( ada.getItem(i).getClass().equals(android.preference.PreferenceScreen.class) ) {
				result = findPreferenceScreenForPreference( key, (PreferenceScreen) ada.getItem(i) );
				if( result != null ) {
					Log.i("RESULTER",result.getKey());
					return result;
				}
			}
		}

		return null;
	}

	private Preference findSubPreference( String key ) {
		PreferenceScreen screen = findPreferenceScreenForPreference( key, null );
		if( screen != null ) {
			Log.i("SCREEN",screen.getKey());
			Preference ff = screen.findPreference(key);
			Log.i("SCREEN",key + " equals " +ff.getKey());
			return screen.findPreference(key);
			//screen.onItemClick(null, null, findPreference(key).getOrder(), 0);
		}
		return null;
	}

	private void openPreference( String key ) {
		PreferenceScreen screen = findPreferenceScreenForPreference( key, null );
		if( screen != null ) {
			screen.onItemClick(null, null, findPreference(key).getOrder(), 0);
		}
	}



 */